package com.netease.xone.widget;

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.ScrollView;

public class NonBlockScrollView extends ScrollView {
	private static boolean DEBUG = false;
	private static final String TAG = NonBlockScrollView.class.getSimpleName();
	private final ArrayList<View> mListViewChildren = new ArrayList<View>();
	private final HashMap<View, Rect> mListViewLocation = new HashMap<View, Rect>();

	public NonBlockScrollView(Context context) {
        super(context);
    }
    public NonBlockScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public NonBlockScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
    	boolean bRes = false;
    	
    	do {
    		switch (ev.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				bRes = !computeChildrenAndLocationOnScreen();
				break;
			case MotionEvent.ACTION_MOVE:
				break;
			case MotionEvent.ACTION_UP:
				break;
			case MotionEvent.ACTION_CANCEL:
				break;
			default:
				break;
			}
    		if (!bRes) {
    			bRes = super.onInterceptTouchEvent(ev);
    		}
    	} while(false);
    	
    	if (DEBUG) {
			switch (ev.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				Log.d(TAG, "onInterceptTouchEvent MotionEvent.ACTION_DOWN" + " bRes=" + bRes);
				break;
			case MotionEvent.ACTION_MOVE:
				Log.d(TAG, "onInterceptTouchEvent MotionEvent.ACTION_MOVE" + " bRes=" + bRes);
				break;
			case MotionEvent.ACTION_UP:
				Log.d(TAG, "onInterceptTouchEvent MotionEvent.ACTION_UP" + " bRes=" + bRes);
				break;
			case MotionEvent.ACTION_CANCEL:
				Log.d(TAG, "onInterceptTouchEvent MotionEvent.ACTION_CANCEL" + " bRes=" + bRes);
				break;
			default:
				break;
			}
		}
    	return bRes;
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
    	boolean bRes = false;
    	
    	do {
    		switch (ev.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				break;
			case MotionEvent.ACTION_MOVE:
				break;
			case MotionEvent.ACTION_UP:
				break;
			case MotionEvent.ACTION_CANCEL:
				break;
			default:
				break;
			}
    		bRes = super.onTouchEvent(ev);
    	} while(false);
    	
    	if (DEBUG) {
			switch (ev.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				Log.d(TAG, "onTouchEvent MotionEvent.ACTION_DOWN" + " bRes=" + bRes);
				break;
			case MotionEvent.ACTION_MOVE:
				Log.d(TAG, "onTouchEvent MotionEvent.ACTION_MOVE" + " bRes=" + bRes);
				break;
			case MotionEvent.ACTION_UP:
				Log.d(TAG, "onTouchEvent MotionEvent.ACTION_UP" + " bRes=" + bRes);
				break;
			case MotionEvent.ACTION_CANCEL:
				Log.d(TAG, "onTouchEvent MotionEvent.ACTION_CANCEL" + " bRes=" + bRes);
				break;
			default:
				break;
			}
		}
    	
    	return bRes;
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    	super.onLayout(changed, l, t, r, b);
    	getChildrenAndLocationOnScreen(this);
    }
    
    private void getChildrenAndLocationOnScreen(View root) {
    	if (root instanceof ListView) {
    		int []location = new int[2];
    		Rect rect = new Rect();
    		root.getGlobalVisibleRect(rect);
    		root.getLocationOnScreen(location);
    		if (!mListViewChildren.contains(root)) {
    			mListViewChildren.add(root);
    		}
    		mListViewLocation.put(root, rect);
    		if (DEBUG) {
    			Log.d(TAG, root.toString());
				Log.d(TAG, "location[0]=" + location[0] + " location[1]=" + location[1]);
				Log.d(TAG, "GlobalVisibleRect=" + rect.toString());
				Log.d(TAG, "\n");
			}
        } else if (root instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) root;
            final int childCount = viewGroup.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = viewGroup.getChildAt(i);
                getChildrenAndLocationOnScreen(child);
            }
        }
    }
    
    private boolean computeChildrenAndLocationOnScreen() {
    	boolean bRes = false;
    	for (View child : mListViewChildren) {
    		Rect rect = new Rect();
    		child.getGlobalVisibleRect(rect);
    		if (DEBUG) {
    			Log.d(TAG, "GlobalVisibleRect=" + rect.toString());
    		}
    		for (Rect rt : mListViewLocation.values()) {
    			if (rect.top == rt.top && rect.bottom == rt.bottom) {
    				if (DEBUG) {
    	    			Log.d(TAG, "equals:" + rt.toString());
    	    		}
    				bRes = true;
    				break;
    			}
    		}
    		if (DEBUG) {
    			Log.d(TAG, "\n");
    		}
    		if (bRes) {
    			break;
    		}
    	}
    	
    	return bRes;
    }
}
